use crate::{errors::AppError};
use bcrypt::{ verify};
use jsonwebtoken::{encode, Header, EncodingKey};
use chrono::{Utc, Duration};
use serde::{Deserialize, Serialize};

const SECRET_KEY: &str = "my_secret_key";

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    sub: String, // 用户id
    exp: usize, // 过期时间
}

// pub fn hash_password(password: &str) -> Result<String, AppError> { 
//     hash(password, DEFAULT_COST).map_err(|e| AppError::InternalServerError(e.to_string()))
// }

pub fn verify_password(password: &str, hash: &str) -> Result<bool, AppError> { 
    verify(password, hash).map_err(|e| AppError::InternalServerError(e.to_string()))
}

pub fn create_jwt(user_id : &String) -> Result<String, AppError> { 
    let exp = Utc::now()
    .checked_add_signed(Duration::hours(24))
    .expect("valid timestamp")
    .timestamp() as usize;

    let claims = Claims { sub: user_id.to_string(), exp };

    encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(SECRET_KEY.as_bytes()),
    ).map_err(|e| AppError::InternalServerError(e.to_string()))
}

// pub fn decode_jwt(token: &str) -> Result<Claims, AppError> { 
//     decode::<Claims>(
//         token,
//         &DecodingKey::from_secret(SECRET_KEY.as_bytes()),
//         &Validation::default(),
//     ).map(|data| data.claims)
//     .map_err(|e| AppError::Unauthorized(e.to_string()))
// }